package com.jewaton.auth.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 自定义用户名密码登录参数
 * 主要加上校验码
 * 将用户对象放session中
 */
public class MyUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {

    private static final Logger logger = LoggerFactory.getLogger(MyUsernamePasswordAuthenticationFilter.class);
	
	// 定义从前台接收验证码参数的 属性名称
	private String validationParameter = "validationCode";

	//配置文件设置是不打开验证码
	private boolean openValidation = true;
	
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		//必须POST提交
		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException(
					"Authentication method not supported: "
							+ request.getMethod());
		}

		String username = obtainUsername(request).trim();
		String password = obtainPassword(request).trim();

		// 验证码是否打开
		if (openValidation) {
            //验证码是否正确，不正确会排出异常
			checkValidateCode(request);
		}

		// 实现 Authentication,这里装进去的password会通过spring的MD5加密,然后实现校验
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, password);
		// 允许子类设置详细属性
		setDetails(request, authRequest);
		
		// 运行UserDetailsService的loadUserByUsername 再次封装Authentication
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	@Override
	protected String obtainUsername(HttpServletRequest request) {
		Object obj = request.getParameter(getUsernameParameter());
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainPassword(HttpServletRequest request) {
		Object obj = request.getParameter(getPasswordParameter());
		return null == obj ? "" : obj.toString();
	}
	
	protected String obtainSessionValidationString(HttpServletRequest request) {
		Object obj = request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		return null == obj ? "" : obj.toString();
	}

	protected String obtainValidationString(HttpServletRequest request) {
		Object obj = request.getParameter(validationParameter);
		return null == obj ? "" : obj.toString();
	}

	public void checkValidateCode(HttpServletRequest request) {

		//获取系统生成的验证码
		String sessionCode = obtainSessionValidationString(request).trim();
		//获取用户输入的验证码
		String inputCode = obtainValidationString(request).trim();
		if (StringUtils.isEmpty(sessionCode))
			throw new BadCredentialsException("验证码超时！！！");
		
		if(logger.isDebugEnabled()){
			logger.debug("系统验证码为："+sessionCode+"，输入验证码为："+inputCode);
		}
		boolean b = sessionCode.equalsIgnoreCase(inputCode);
		if (!b)
			throw new BadCredentialsException("验证码不匹配！！！");
	}
	
	public void setValidationParameter(String validationParameter) {
		this.validationParameter = validationParameter;
	}
	
	public void setOpenValidation(boolean openValidation) {
		this.openValidation = openValidation;
	}
	
}
